package com.quick.develop.flowable.service.process.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quick.develop.framework.security.utils.SecurityUtils;
import com.quick.develop.flowable.application.impl.BpmTaskAssigneeApplicationImpl;
import com.quick.develop.flowable.domain.rule.BpmExampleRule;
import com.quick.develop.flowable.mapper.BpmExampleRuleMapper;
import com.quick.develop.flowable.service.process.IBpmExampleRuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Service
@Slf4j
public class BpmExampleRuleServiceImpl extends ServiceImpl<BpmExampleRuleMapper, BpmExampleRule> implements IBpmExampleRuleService {
    private BpmTaskAssigneeApplicationImpl bpmTaskAssigneeApplicationImpl;

    @Override
    public BpmExampleRule getBpmExampleRule(BpmExampleRule bpmExampleRule) {
        List<BpmExampleRule> list = baseMapper.getBpmExampleRule(bpmExampleRule);
        if(list.size()>0){
            return list.get(0);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BpmExampleRule addBpmExampleRule(BpmExampleRule bpmExampleRule) {
        //去重  根据流程实例id或者bussKey 和节点id 去重
        if(!"".equals(bpmExampleRule.getId()) && !"null".equals(bpmExampleRule.getId()) && bpmExampleRule.getId()!=null){
//            baseMapper.update(bpmExampleRule);
            baseMapper.updateBatch(bpmExampleRule);
        }else{
            baseMapper.removeAll(bpmExampleRule);
            baseMapper.insert(bpmExampleRule);
        }
        return getBpmExampleRule(bpmExampleRule);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String creatNewRule(Map<String, String> map) {

        String code = "200";
        List<BpmExampleRule> list = baseMapper.getBpmExampleRuleByBussKey(map.get("oldBusinessKey"));
        for(BpmExampleRule obj : list){
            obj.setBusinessKey(map.get("newBusinessKey"));
            obj.setId(null);
        }
        baseMapper.insertBatch(list);
        return code;
    }

    @Override
    public String isHashCurent(Map<String, String> map) {
        BpmExampleRule bpmExampleRule = new BpmExampleRule();
        String handlerTargetCode = map.get("handlerTargetCode");
        String handlerElseCode = map.get("handlerElseCode");
        bpmExampleRule.setBusinessKey(map.get("businessKey"));
        bpmExampleRule.setNodeCode(handlerTargetCode);

        List<BpmExampleRule> list = baseMapper.getBpmExampleRuleByCodeAndKey(bpmExampleRule);
        BpmExampleRule obj = new BpmExampleRule();
        if(list.size()>0){
            obj = list.get(0);
            //判断角色中是否有当前登录用户
            if(isHashUserId(obj.getOptionsPersonnel(),SecurityUtils.getUserCode())){
                return handlerElseCode;
            }
            //判断部门中是否有当前登录用户
            if(obj.getOptionsDept().size()>0 && isHashUserId(bpmTaskAssigneeApplicationImpl.calculateTaskCandidateUsersByDeptMember(obj.getOptionsDept()), SecurityUtils.getUserCode())){
                return handlerElseCode;
            }
            //判断
            if(obj.getOptionsRole().size()>0 && isHashUserId(bpmTaskAssigneeApplicationImpl.calculateTaskCandidateUsersByRole(obj.getOptionsRole()),SecurityUtils.getUserCode())){
                return handlerElseCode;
            }
        }
        return handlerTargetCode;
    }

    @Override
    public JSONObject getNodeCode(Map<String, String> map) {
        BpmExampleRule bpmExampleRule = baseMapper.getBpmExampleNodeRule(map);
        JSONObject jsonObject = new JSONObject();
        if(bpmExampleRule!=null){
            String jsonStr = JSON.toJSONString(bpmExampleRule);
            jsonObject = JSON.parseObject(jsonStr);
        }
        return jsonObject;
    }

    @Override
    public String updateNodeCode(Map<String, String> map) {
        BpmExampleRule bpmExampleRule = baseMapper.getBpmExampleNodeRule(map);
        Set<String> set = new HashSet<>();
        set.add(map.get("userCode"));
        if(bpmExampleRule==null) {
            bpmExampleRule = new BpmExampleRule();
            bpmExampleRule.setBusinessKey(map.get("businessKey"));
            bpmExampleRule.setModelKey(map.get("modelKey"));
            bpmExampleRule.setNodeCode(map.get("nodeCode"));
        }
        Set<String> option = new HashSet<>();
        bpmExampleRule.setOptionsPersonnel(set);
        bpmExampleRule.setOptionsDept(option);
        bpmExampleRule.setOptionsRole(option);
        BpmExampleRule mm = addBpmExampleRule(bpmExampleRule);
        return "200";
    }

    @Override
    public String checkRequired(Map<String, Object> map) {
        List<Map<String,String>> list = (List<Map<String,String>>)map.get("checklist");
        List<BpmExampleRule> listRule = baseMapper.getBpmExampleRuleByBussKey(String.valueOf(map.get("businessKey")));
        String result = "Y";
        /**
         * 需要先将要校验的节点选出来
         * 目前全部节点需要校验
         */
        Map<String,Map<String,String>> checkMap = new HashMap<>();
        for(Map<String,String> oldMap : list){
            checkMap.put(oldMap.get("nodeCode"),oldMap);
        }

        /**
         *
         */
        Map<String,BpmExampleRule> checkRepeatMap = new HashMap<>();
        List<String> checkRepeatList = (List<String>)map.get("notRepeatList");

        for(BpmExampleRule obj:listRule){
            checkRepeatMap.put(obj.getNodeCode(),obj);
            if(checkMap.get(obj.getNodeCode())!=null){
                if(obj.getOptionsPersonnel().size()==0 &&  obj.getOptionsDept().size()==0 && obj.getOptionsRole().size()==0){
                    result = checkMap.get(obj.getNodeCode()).get("nodeName") +"节点不能为空!";
                    break;
                }
            }
        }
        /**
         * 校验 节点不能存在重复的处理人(目前只校验人员 不校验部门、角色)
         * 存在两个节点时才做处理
         * 循环比较
         * 当前节点和后续 所有的节点做比较
         */
        boolean flag = true;//是否继续校验
        if( "Y".equals(result) && checkRepeatList!=null && checkRepeatList.size()>1 ){
            for(int i =0;i<checkRepeatList.size()-1;i++){
                if(flag){
                    for(int j=i+1;j<checkRepeatList.size();j++){
                        if(hashRepeatPerson(checkRepeatMap.get(checkRepeatList.get(i)),checkRepeatMap.get(checkRepeatList.get(j)))){
                            flag = false;
                            result  = checkMap.get(checkRepeatList.get(i)).get("nodeName")+"节点和"+ checkMap.get(checkRepeatList.get(j)).get("nodeName")+"节点存在相同的人员!不允许存在相同的处理人";
//                            result  = "存在相同的人员!不允许存在相同的处理人";
                            break;
                        }
                    }
                }else{
                    break;
                }
            }
        }
        return result;
    }

    /**
     * 两个对象中是否存在重复的人员
     * @return true 存在 ;   false 不存在
     */
    public boolean hashRepeatPerson(BpmExampleRule obj1,BpmExampleRule obj2){
        boolean res =  false;

        Set<String> ope1 = obj1.getOptionsPersonnel();
        Set<String> ope2 = obj2.getOptionsPersonnel();
        Set<String> ope3 = new HashSet<String>();
        int oldSize = ope1.size()+ope2.size();//原人员大小
        if(oldSize==0){
            return res;
        }
        ope3.addAll(ope1);
        ope3.addAll(ope2);
        if(oldSize>ope3.size()){
            res = true;
        }
        return res;
    }



    /**
     * 判断set中是否存在用户id
     * @param set
     * @param userId
     * @return
     */
    public Boolean isHashUserId(Set<String> set, String userId){
        int num = set.size();
        if(set.size()>0){
            set.add(userId);
            if(set.size()==num){
                return true;
            }
        }
        return false;
    }

}
